/**
 * WebRTC音视频录制
 * 
 * @function getUserMedia 开启WebRTC
 * @function SaveImage 根据当前流，保存图片
 * @function StartRecord 录制音视频
 */

// 设备下的所有视频音频输入输出设备
export const EnumerateDevices = []
export const EnumerateDevicesKind = {}

// 老版本浏览器没有实现 mediaDevices
if (navigator.mediaDevices === undefined) {
    navigator.mediaDevices = {}
}

export const isWebRTC = !!(navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia)

// mediaDevices兼容老版本
if (navigator.mediaDevices.getUserMedia === undefined) {
    const getUserMedia =
        navigator.getUserMedia ||
        navigator.webkitGetUserMedia ||
        navigator.mozGetUserMedia ||
        navigator.msGetUserMedia;

    navigator.mediaDevices.getUserMedia = function (constraints) {
        // 一些浏览器根本没实现它 - 那么就返回一个error到promise的reject来保持一个统一的接口
        if (!getUspromiseerMedia) {
            return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
        }

        // 否则，为老的navigator.getUserMedia方法包裹一个Promise
        return new Promise(function (resolve, reject) {
            getUserMedia.call(navigator, constraints, resolve, reject);
        });

    }
}

GetEnumerateDevices()

// 获取设备下的所有视频音频输入输出设备
function GetEnumerateDevices() {
    //判断浏览器是否支持这些 API
    if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
        alert(new Error("enumerateDevices() not supported."))
        console.log(new Error("enumerateDevices() not supported."));
        return;
    }

    navigator.mediaDevices.enumerateDevices()
        .then(function (devices) {
            // 获取音视频输入输出
            devices.forEach(function ({
                deviceId,
                groupId,
                kind,
                label
            }) {
                const data = {
                    deviceId,
                    groupId,
                    kind,
                    label
                }

                EnumerateDevices.push(data)

                if (EnumerateDevicesKind[kind]) {
                    EnumerateDevicesKind[kind].push(data)
                } else {
                    EnumerateDevicesKind[kind] = [data]
                }
            });
            console.log(EnumerateDevices)
            console.log(EnumerateDevicesKind)
        })
        .catch(function (err) {
            console.log("获取视频音频输入输出设备报错");
            console.log(err.name + ": " + err.message);
        });
}

/**
 * WebRTC音视频录制
 * 
 * @function getUserMedia 
 * @param mediaStreamContrains 轨道配置 {
 *   audio:{
 *     echoCancellation 回音消除
 *     noiseSuppression 噪声抑制
 *     autoGainControl 增益控制
 *   }
 * }
 * @returns 返回Promise getUserMedia，resolve 返回流
 */
export const getUserMedia = function (
    mediaStreamContrains = {
        video: true,
        audio: {
            echoCancellation: true,
            noiseSuppression: true,
            autoGainControl: true
        }
    }
) {
    return navigator.mediaDevices.getUserMedia(mediaStreamContrains)
}

/**
 * 保存图片
 * @function SaveImage 根据视频保存图片
 * @param width 图片宽度
 * @param height 图片高度
 * @param VideoStream video标签实例
 * @param ImageName 下载图片名称
 * @param DownLoad 是否下载图片
 * @returns image图片数据
 */
export function SaveImage({
    width = 640,
    height = 480,
    VideoStream,
    ImageName = "下载",
    DownLoad = true
}) {
    if (!VideoStream) {
        // 确保Video在获取WebRTC流数据
        return console.log(new Error("请传入Video"))
    }

    let canvas = document.createElement("canvas");
    // 配置canvas尺寸
    canvas.width = width
    canvas.height = height

    document.body.appendChild(canvas);
    // 配置照片尺寸
    canvas.getContext('2d').drawImage(VideoStream, 0, 0, width, height);

    const image = canvas.toDataURL("image/jpeg");
    if (DownLoad) {
        let OA = document.createElement("a");
        OA.download = ImageName;
        OA.href = image
        document.body.appendChild(OA);
        OA.click();
        OA.remove(); // 下载之后把创建的元素删除
    }
    canvas.remove();

    return image
}

// 
let RecordBuffer = []
// MediaRecorder实例
let mediaRecorder = null
/**
 * 录制视频
 * @function startRecord 开始录制音视频
 * @param mimeType 录制音视频格式
 * @returns Promise resolve返回 mediaRecorder 实例
 */
export function StartRecord(
    Stream,
    mimeType = "",
) {
    return new Promise((resolve, reject) => {
        if (!Stream) {
            console.error(`Stream is not supported!`);
            reject()
            return
        }
        // 重新开始清空数据
        RecordBuffer = [];

        //设置录制下来的多媒体格式       
        let options = {
            mimeType: mimeType
        }

        //判断浏览器是否支持录制  
        if (!MediaRecorder.isTypeSupported(options.mimeType)) {
            console.error(`${options.mimeType} is not supported!`);
            return;
        }

        try { //创建录制对象               
            mediaRecorder = new MediaRecorder(Stream, options);

            //当有音视频数据来了之后触发该事件       
            mediaRecorder.ondataavailable = handleDataAvailable
            //开始录制        
            mediaRecorder.start(10);

            resolve(mediaRecorder)
        } catch (e) {
            console.error('Failed to create MediaRecorder:', e);
            reject(e)
        }
    })
}

function handleDataAvailable(e) {
    if (e && e.data && e.data.size > 0) {
        RecordBuffer.push(e.data);
    }
}

// 返回录制下的所有Blob文件
export function GetMediaBlob() {
    if (!mediaRecorder) return

    // 录制中或暂停，获取最后一帧
    if (mediaRecorder.state !== 'inactive') {
        mediaRecorder.requestData()
    }
    return RecordBuffer
}